////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2010.
// -------------------------------------------------------------------------
//  File name:   CWBufferCuller.h
//  Version:     v1.00
//  Created:     32/05/2010 by Peter Bajusz.
//  Compilers:   Visual Studio.NET
//  Description: Occlusion Culler using software WBuffer rendering
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////
#if OCCLUSIONCULLER != CWBufferCuller
# define _WBUFFERCULLER_H
#endif
#ifndef _WBUFFERCULLER_H
#define _WBUFFERCULLER_H
#pragma once

class CWBufferCuller : public Cry3DEngineBase
{
public:
	CWBufferCuller();
	~CWBufferCuller();
	// start new frame
	void BeginFrame(const CCamera &rCam);
	// render into buffer
	void AddRenderMesh(IRenderMesh *pRM, Matrix34A *pTranRotMatrix, IMaterial *pMaterial, bool bOutdoorOnly, bool bCompletelyInFrustum, bool bNoCull);
	//void AddHeightMap(const struct SRangeInfo & m_rangeInfo, float X1, float Y1, float X2, float Y2);
	void AddOccluderPlane(Vec3 _vertices[4]);

	// test visibility
	bool IsObjectVisible(const AABB &_objBox, EOcclusionObjectType eOcclusionObjectType, float fDistance, uint32 *pRetVal = NULL) const;

	// Extrude and test shadowcasterBBox visibility
	//bool IsShadowcasterVisible(const AABB &objBox, Vec3 rExtrusionDir);

	// draw content to the screen for debug
	void DrawDebug(int nStep);

	// return current camera
	const CCamera &GetCamera() const { return m_Camera; }

	void GetMemoryUsage(ICrySizer *pSizer) const;

	void SetFrameTime(float fTime) { m_FrameTime = fTime; }
	float GetFrameTime() const { return m_FrameTime; }
	bool IsOutdooVisible() const { return true; }
	int TrisWritten() const { return m_TrisWritten; }
	int ObjectsWritten() const { return m_ObjectsWritten; }
	int TrisTested() const { return m_TrisTested; }
	int ObjectsTested() const { return m_ObjectsTested; }
	int ObjectsTestedAndRejected() const { return m_ObjectsTestedAndRejected; }
	int SelRes() const { return 0; }
	//float FixedZFar()const;
	float GetZNearInMeters() const { return 0; }
	float GetZFarInMeters() const { return 0; }

private:
	CCamera m_Camera;
	float m_NearZ;
	float	m_FrameTime;
	uint32 m_TrisWritten;
	uint32 m_ObjectsWritten;
	mutable uint32 m_TrisTested;
	mutable uint32 m_ObjectsTested;
	mutable uint32 m_ObjectsTestedAndRejected;
	int m_DebugTextureID;

	int m_Width, m_Height;
	float *m_Buffer;
	int m_SuperWidth, m_SuperHeight;
	float *m_SuperBuffer;
	uint8 *m_DebugBuffer;

	Matrix34 m_MatViewProj;
	PodArray<Vec3> m_VertexCache;

	void InitStats();
	void FreeBuffers();
	void ClipAndDrawTriangle(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2);
	void DrawTriangle(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2);
	bool TestQuad(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3) const;
};

#endif
